home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_unix / j109lxa4.tar / ax25subr.c < prev    next >
C/C++ Source or Header  |  1994-06-04  |  6KB  |  279 lines

  1. /* low level AX25 routines:
  2.  * callsign conversion
  3.  * control block management
  4.  *
  5.  * Copyright 1991 Phil Karn, KA9Q
  6.  */
  7.  /* Mods by G1EMM */
  8. #include <stdio.h>
  9. #include "global.h"
  10. #include "config.h"
  11. #ifdef AX25
  12. #include "mbuf.h"
  13. #include "timer.h"
  14. #include "ax25.h"
  15. #include "lapb.h"
  16. #include <ctype.h>
  17.  
  18. struct ax25_cb *Ax25_cb;
  19.  
  20. /* Default AX.25 parameters */
  21. int32 T3init = 0;        /* No keep-alive polling */
  22. int32 T4init = 300;        /* 5 Minutes of no I frame tx or rx => redundant link */
  23. int16 Maxframe = 1;        /* Stop and wait */
  24. int16 N2 = 10;            /* 10 retries */
  25. int16 Axwindow = 2048;        /* 2K incoming text before RNR'ing */
  26. int16 Paclen = 256;        /* 256-byte I fields */
  27. int16 Pthresh = 128;        /* Send polls for packets larger than this */
  28. int32 Axirtt = 5000;        /* Initial round trip estimate, ms */
  29. int16 Axversion = V2;        /* Protocol version */
  30. int32 Blimit = 30;        /* Retransmission backoff limit */
  31.  
  32. /* Look up entry in connection table
  33.  * Check BOTH the source AND destination address
  34.  * Added 11/15/91, WG7J/PA3DIS
  35.  */
  36. struct ax25_cb *
  37. find_ax25(local,remote,iface)
  38. char *local;
  39. char *remote;
  40. struct iface *iface;
  41. {
  42.     register struct ax25_cb *axp;
  43.     struct ax25_cb *axlast = NULLAX25;
  44.  
  45.     /* Search list */
  46.     for(axp = Ax25_cb; axp != NULLAX25;axlast=axp,axp = axp->next){
  47.         if(addreq(axp->remote,remote) && addreq(axp->local,local) \
  48.                 && axp->iface == iface) {
  49.             if(axlast != NULLAX25){
  50.                 /* Move entry to top of list to speed
  51.                  * future searches
  52.                  */
  53.                 axlast->next = axp->next;
  54.                 axp->next = Ax25_cb;
  55.                 Ax25_cb = axp;
  56.             }
  57.             return axp;
  58.         }
  59.     }
  60.     return NULLAX25;
  61. }
  62.  
  63.  
  64. /* Remove address entry from connection table */
  65. void
  66. del_ax25(conn)
  67. struct ax25_cb *conn;
  68. {
  69.     register struct ax25_cb *axp;
  70.     struct ax25_cb *axlast = NULLAX25;
  71.  
  72.     for(axp = Ax25_cb; axp != NULLAX25; axlast=axp,axp = axp->next){
  73.         if(axp == conn)
  74.             break;
  75.     }
  76.  
  77.     if(axp == NULLAX25)
  78.         return;        /* Not found */
  79.  
  80.     /* Remove from list */
  81.     if(axlast != NULLAX25)
  82.         axlast->next = axp->next;
  83.     else
  84.         Ax25_cb = axp->next;
  85.  
  86.     /* Timers should already be stopped, but just in case... */
  87.     stop_timer(&axp->t1);
  88.     stop_timer(&axp->t3);
  89.     stop_timer(&axp->t4);
  90.  
  91.     axp->r_upcall = NULLVFP((struct ax25_cb*,int));
  92.     axp->s_upcall = NULLVFP((struct ax25_cb*,int,int));
  93.     axp->t_upcall = NULLVFP((struct ax25_cb*,int));
  94.  
  95.     /* Free allocated resources */
  96.     free_q(&axp->txq);
  97.     free_q(&axp->rxasm);
  98.     free_q(&axp->rxq);
  99.     free((char *)axp);
  100. }
  101.  
  102. /* Create an ax25 control block. Allocate a new structure, if necessary,
  103.  * and fill it with all the defaults.
  104.  */
  105. /* This takes BOTH source and destination address.
  106.  * 11/15/91, WG7J/PA3DIS
  107.  */
  108. struct ax25_cb *
  109. cr_ax25(local,remote,iface)
  110. char *local;
  111. char *remote;
  112. struct iface *iface;
  113. {
  114.     register struct ax25_cb *axp;
  115.  
  116.     if((remote == NULLCHAR) || (local == NULLCHAR))
  117.         return NULLAX25;
  118.  
  119.     /* Create an entry
  120.      * and insert it at the head of the chain
  121.      */
  122.     axp = (struct ax25_cb *)callocw(1,sizeof(struct ax25_cb));
  123.     axp->next = Ax25_cb;
  124.     Ax25_cb = axp;
  125.  
  126.     /*fill in 'defaults'*/
  127.     memcpy(axp->local,local,AXALEN);
  128.     memcpy(axp->remote,remote,AXALEN);
  129.     axp->user = -1;
  130.     axp->state = LAPB_DISCONNECTED;
  131.     axp->maxframe = Maxframe;
  132.     axp->window = Axwindow;
  133.     axp->iface = iface;
  134.     axp->paclen = iface->paclen;
  135.     axp->proto = Axversion;    /* Default, can be changed by other end */
  136.     axp->pthresh = Pthresh;
  137.     axp->n2 = N2;
  138.     axp->srt = Axirtt;
  139.     set_timer(&axp->t1,2*axp->srt);
  140.     axp->t1.func = recover;
  141.     axp->t1.arg = axp;
  142.  
  143.     set_timer(&axp->t3,T3init);
  144.     axp->t3.func = pollthem;
  145.     axp->t3.arg = axp;
  146.  
  147.     set_timer(&axp->t4,T4init * 1000L);
  148.     axp->t4.func = redundant;
  149.     axp->t4.arg = axp;
  150.  
  151.     /* Always to a receive and state upcall as default */
  152.     /* Also bung in a default transmit upcall - in case */
  153.     axp->r_upcall = s_arcall;
  154.     axp->s_upcall = s_ascall;
  155.     axp->t_upcall = s_atcall;
  156.  
  157.     return axp;
  158. }
  159.  
  160. /*
  161.  * setcall - convert callsign plus substation ID of the form
  162.  * "KA9Q-0" to AX.25 (shifted) address format
  163.  *   Address extension bit is left clear
  164.  *   Return -1 on error, 0 if OK
  165.  */
  166. int
  167. setcall(out,call)
  168. char *out;
  169. char *call;
  170. {
  171.     int csize;
  172.     unsigned ssid;
  173.     register int i;
  174.     register char *dp;
  175.     char c;
  176.  
  177.     if(out == NULLCHAR || call == NULLCHAR || *call == '\0')
  178.         return -1;
  179.  
  180.     /* Find dash, if any, separating callsign from ssid
  181.      * Then compute length of callsign field and make sure
  182.      * it isn't excessive
  183.      */
  184.     dp = strchr(call,'-');
  185.     if(dp == NULLCHAR)
  186.         csize = strlen(call);
  187.     else
  188.         csize = dp - call;
  189.     if(csize > ALEN)
  190.         return -1;
  191.     /* Now find and convert ssid, if any */
  192.     if(dp != NULLCHAR){
  193.         dp++;    /* skip dash */
  194.         ssid = atoi(dp);
  195.         if(ssid > 15)
  196.             return -1;
  197.     } else
  198.         ssid = 0;
  199.     /* Copy upper-case callsign, left shifted one bit */
  200.     for(i=0;i<csize;i++){
  201.         c = *call++;
  202.         if(islower(c))
  203.             c = toupper(c);
  204.         *out++ = c << 1;
  205.     }
  206.     /* Pad with shifted spaces if necessary */
  207.     for(;i<ALEN;i++)
  208.         *out++ = ' ' << 1;
  209.     
  210.     /* Insert substation ID field and set reserved bits */
  211.     *out = 0x60 | (ssid << 1);
  212.     return 0;
  213. }
  214. int
  215. addreq(a,b)
  216. register char *a,*b;
  217. {
  218.     if(memcmp(a,b,ALEN) != 0 || ((a[ALEN] ^ b[ALEN]) & SSID) != 0)
  219.         return 0;
  220.     else
  221.         return 1;
  222. }
  223. /* Convert encoded AX.25 address to printable string */
  224. char *
  225. pax25(e,addr)
  226. char *e;
  227. char *addr;
  228. {
  229.     register int i;
  230.     char c;
  231.     char *cp;
  232.  
  233.     cp = e;
  234.     for(i=ALEN;i != 0;i--){
  235.         c = (*addr++ >> 1) & 0x7f;
  236.         if(c != ' ')
  237.             *cp++ = c;
  238.     }
  239.     if ((*addr & SSID) != 0)
  240.         sprintf(cp,"-%d",(*addr >> 1) & 0xf);    /* ssid */
  241.     else
  242.         *cp = '\0';
  243.     return e;
  244. }
  245.  
  246. /* Figure out the frame type from the control field
  247.  * This is done by masking out any sequence numbers and the
  248.  * poll/final bit after determining the general class (I/S/U) of the frame
  249.  */
  250. int16
  251. ftype(control)
  252. register int control;
  253. {
  254.     if((control & 1) == 0)    /* An I-frame is an I-frame... */
  255.         return I;
  256.     if(control & 2)        /* U-frames use all except P/F bit for type */
  257.         return (int16)(uchar(control) & ~PF);
  258.     else            /* S-frames use low order 4 bits for type */
  259.         return (int16)(uchar(control) & 0xf);
  260. }
  261.  
  262. #ifndef UNIX
  263.  
  264. void
  265. lapb_garbage(red)
  266. int red;
  267. {
  268.     register struct ax25_cb *axp;
  269.  
  270.     for(axp=Ax25_cb;axp != NULLAX25;axp = axp->next){
  271.         mbuf_crunch(&axp->rxq);
  272.         mbuf_crunch(&axp->rxasm);
  273.     }
  274. }
  275.  
  276. #endif
  277. #endif /* AX25 */
  278.  
  279.